/*
Automatic clinic tests using a robot arm.
Copyright (C) 2010  CIC-CPC, CHU Gabriel Montpied
All other trademarks, logos and copyrights are the property
of their respective owners.

This file is part of cpc-painbot.

cpc-painbot is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

cpc-painbot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with cpc-painbot.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "indicateurprocess.h"

#include "qserialdevice/abstractserial.h"

#include <QTimerEvent>
#include <QDebug>

#include "capteur.h"
#include "commande/indproc/ascii.h"
#include "commande/indproc/reponseindicateur.h"

IndicateurProcess::IndicateurProcess(QObject *parent)
:PilotableSerie(parent),
intervalle_(100),
etat_(EtatAttente)
{
    using namespace commande::indproc;
    // Création des commandes.
    for (int i = 0; i < Ascii::nbTypes; i++)
        commandes_.append(Ascii::creer(Ascii::Type(i)));
}

IndicateurProcess::~IndicateurProcess()
{
    while ( !commandes_.isEmpty() )
        delete commandes_.takeFirst();
}

void IndicateurProcess::majMin(void)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatLectureMin;
        envoyer(commandes_[Ascii::LireMin]);
    }
}

void IndicateurProcess::resetMin(void)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatResetMin;
        envoyer(commandes_[Ascii::ResetMin]);
        etat_ = EtatAttente;
    }
}

void IndicateurProcess::majMax(void)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatLectureMax;
        envoyer(commandes_[Ascii::LireMax]);
    }
}

void IndicateurProcess::resetMax(void)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatResetMax;
        envoyer(commandes_[Ascii::ResetMax]);
        etat_ = EtatAttente;
    }
}

void IndicateurProcess::majTare(void)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatLectureTare;
        envoyer(commandes_[Ascii::LireTare]);
    }
}

void IndicateurProcess::resetTare(void)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatResetTare;
        envoyer(commandes_[Ascii::ResetTare]);
        etat_ = EtatAttente;
    }
}

void IndicateurProcess::setTare(qreal tare)
{
    using namespace commande::indproc;

    if ( etat_ == EtatAttente ) {
        etat_ = EtatEcritureTare;
        envoyer(commandes_[Ascii::PrendreTare]);
        etat_ = EtatAttente;
    }
}

void IndicateurProcess::mesure(void)
{
    using namespace commande::indproc;
    if ( etat_ == EtatAttente ) {
        etat_ = EtatLireMesure;
        envoyer(commandes_[Ascii::LireMesure]);
    }
}

void IndicateurProcess::setCapteur(Capteur *capteur)
{
    capteur_ = capteur;
}

void IndicateurProcess::setAdresse(int adresse)
{
    //qDebug() << "IndicateurProcess::setAdresse(" << adresse << ")";

    adresse_ = adresse;

    foreach (commande::indproc::Ascii *cmd, commandes_)
        cmd->setAdresse(adresse_);

    emit adresseChangee(adresse_);
}

void IndicateurProcess::timerEvent(QTimerEvent *event)
{
    if ( event->timerId() == timer_.timerId() ) {
        // Nouvelle capture à faire
        mesure();
    } else
        QObject::timerEvent(event);
}

void IndicateurProcess::configurerLiaison(void)
{
    PilotableSerie::configurerLiaison();
    serie_->setBaudRate(AbstractSerial::BaudRate9600);
}

bool IndicateurProcess::hasCommande(void) const
{
    return buffer_.startsWith(' ') && buffer_.contains('\r');
}

void IndicateurProcess::parserCommande(void)
{
    using namespace commande::indproc;
    ReponseIndicateur *rep = ReponseIndicateur::lire(buffer_);
    buffer_.remove(0, buffer_.indexOf('\r') + 1);
    if ( rep != 0 ) {
        //qDebug() << "IndicateurProcess::parserCommande : réponse reçue.";

        switch (etat_) {
            case EtatLectureMin:
                min_ = rep->valeur();
                emit minimumChange(min_);
                break;

            case EtatLectureMax:
                max_ = rep->valeur();
                emit maximumChange(max_);
                break;

            case EtatLectureTare:
                tare_ = rep->valeur();
                emit tareChangee(tare_);
                break;

            case EtatLireMesure:
                capteur_->setMesure(this, rep->valeur());
                break;

            default: break;
        }

        etat_ = EtatAttente;
        delete rep;
    }
}
